package com.book.code;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zhutianyu
 * @date 2022/8/1 14:28
 */
@Slf4j
public class CasCount {
    private AtomicInteger atomicInteger = new AtomicInteger(0);
    private int i = 0;

    @Test
    public void test01() {
        long start = System.currentTimeMillis();

        final CasCount cas = new CasCount();
        CountDownLatch countDownLatch = new CountDownLatch(10000);
        for (int i = 10000; i > 0; i--) {
            new Thread(() -> {
                for (int i1 = 10000; i1 > 0; i1--) {
                    cas.safeCount();
                    cas.count();
                }
                countDownLatch.countDown();
            }).start();
        }
        try {
            countDownLatch.await();
            log.info("执行完毕");
        } catch (InterruptedException e) {
        }

        log.info("atomicInteger = " + cas.atomicInteger.get());
        log.info("i = " + cas.i);
        log.info("执行时间：" + (System.currentTimeMillis() - start));
    }

    /**
     * 使用CAS实现线程安全计数器
     */
    private void safeCount() {
        boolean result;
        do {
            int i = atomicInteger.get();
            result = atomicInteger.compareAndSet(i, ++i);
        } while (!result);
    }

    /**
     * 非线程安全计数器
     */
    private void count() {
        i++;
    }
}
